#!/bin/bash
# Copyright 2011, Dell
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 
# This does a test deploy of Swift

overall_failure=0
die () { local _res=$1; shift; echo "$@"; exit $_res; }

[[ $DEBUG ]] && set -x
set -e

crowbar swift proposal create cluster1
crowbar swift proposal show cluster1 >"$LOGDIR/swift-proposal.json"
crowbar swift proposal commit cluster1 || {
    echo "Swift proposal failed to commit"
    exit 1
}

crowbar swift show cluster1 > "$LOGDIR/swift-cluster1.json"
read proxy < <(sed -n '/"swift-proxy-acct": \[/ { n; p }' \
    "$LOGDIR/swift-cluster1.json")
proxy="${proxy//\"/}."
addr_re='Address: ([0-9.]+)'
if ! [[ $(nslookup "$proxy" "$CROWBAR_IP") =~ $addr_re ]]; then
    crowbar swift show cluster1 >"$LOGDIR/swift-failed.json"
    die 1 "Could not find IP address of the swift proxy ($proxy)"
fi
proxy_ip="${BASH_REMATCH[1]}"

try_with_recovery() {
    for action in 'service memcached-swift-proxy restart' \
	'/etc/init.d/swift-proxy restart' \
	'swift-ring-builder /etc/swift/account.builder' \
	'service swift-account restart' \
	'reboot'; do
        if [[ $(run_on "$proxy_ip" "$@") ]]; then
	    break
	fi
	overall_failure=1
	printf "Trying workaround: %s\n" "$action"
	run_on "$proxy_ip" $action || :
	if [[ $action =~ reboot ]]; then
	    sleep 120
	else
	    sleep 5
	fi
    done
}

crowbar swift show cluster1 >"$LOGDIR/swift-deployed.json"
echo "Swift proxy at $proxy_ip.  Prepping the Storage subsystem..."
try_with_recovery swauth-prep -K swauth -U .super_admin \
    -A 'https://127.0.0.1:8080/auth/'

echo "Creating an account..."
try_with_recovery swauth-add-account -K swauth -U .super_admin \
    -A https://127.0.0.1:8080/auth/ a_test

echo "Creating a user..."
try_with_recovery swauth-add-user -K swauth -U .super_admin \
    -A https://127.0.0.1:8080/auth/ -a a_test test test

auth_hdr=$(mktemp "$LOGDIR/swift-auth-header-XXXXX.txt") || \
    die 1 "Could not make a temp location for the aithentication header."

# get the auth information we will need
while read line; do
    echo "$line" >>"$auth_hdr"
    hdr=${line%%:*}
    param=${line#*:}
    case $hdr in
	X-Storage-Url) storage_url=$param;;
	X-Storage-Token) storage_token=$param;;
	X-Auth-Token) auth_token=$param;;
    esac
done < <(curl -k -D - -H -o /dev/null "X-Auth-User: a_test:test" \
    -H "X-Auth-Key: test" --connect-timeout 30 --max-time 120 \
    https://$proxy_ip:8080/auth/v1.0/)
    
[[ $storage_url && $storage_token && $auth_token ]] || \
    die 1 "Could not get a necessary parameter from the Swift proxy!"

# $1 = http method
# $2 = pathname for swift
# $3 = local path (optional)
do_swift() {
    local curlargs=(-k -D - 
	-H "X-Auth-Token: $auth_token"
	-H "X-Auth-User: a_test:test"
	-X "$1"
	"$storage_url/$2")
    if [[ $3 && $1 = PUT ]]; then
	curlargs+=(-T "$3")
    elif [[ $3 && $1 = GET ]]; then
	curlargs+=(-o "$3")
    fi
    curl "${curlargs[@]}" || return 1
}

echo "Testing Swift functionality..."
do_swift PUT testdir || die 1 "Could not create a directory in Swift"
testfile=$(mktemp "$LOGDIR/swift-testfile-XXXXX")
outfile=$(mktemp "$LOGDIR/swift-outfile-XXXXX")
dd if=/dev/urandom "of=$testfile" bs=64K count=1
do_swift PUT testdir/testfile "$testfile" || \
    die 1 "Could not store random information into Swift"
do_swift GET testdir/testfile "$outfile" || \
    die 1 "Could not get our random data back from Swift"
echo "Swift deploy passed."
exit $overall_failure

